home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / pcl / src-16f.lha / compiler / mips / mips-insts.lisp < prev    next >
Encoding:
Text File  |  1991-11-17  |  22.7 KB  |  791 lines

  1. ;;; -*- Package: MIPS -*-
  2. ;;;
  3. ;;; **********************************************************************
  4. ;;; This code was written as part of the CMU Common Lisp project at
  5. ;;; Carnegie Mellon University, and has been placed in the public domain.
  6. ;;; If you want to use this code or any part of CMU Common Lisp, please contact
  7. ;;; Scott Fahlman or slisp-group@cs.cmu.edu.
  8. ;;;
  9. (ext:file-comment
  10.   "$Header: mips-insts.lisp,v 1.34 91/11/17 17:08:12 wlott Exp $")
  11. ;;;
  12. ;;; **********************************************************************
  13. ;;;
  14. ;;; $Header: mips-insts.lisp,v 1.34 91/11/17 17:08:12 wlott Exp $
  15. ;;;
  16. ;;; Description of the MIPS architecture.
  17. ;;;
  18. ;;; Written by William Lott
  19. ;;;
  20.  
  21. #|
  22. (eval-when (compile load eval)
  23.   (unless (find-package "OLD-MIPS")
  24.     (rename-package (find-package "MIPS") "OLD-MIPS" '("VM"))))
  25. |#
  26.  
  27. (in-package "MIPS")
  28. (use-package "ASSEM")
  29. (use-package "EXT")
  30.  
  31. (disassem:set-disassem-params :instruction-alignment 32) 
  32.  
  33.  
  34. ;;;; Resources.
  35.  
  36. (define-resources high low memory float-status)
  37.  
  38.  
  39. ;;;; Special argument types and fixups.
  40.  
  41. (defun register-p (object)
  42.   (and (tn-p object)
  43.        (let* ((sc (tn-sc object))
  44.           (sc-name (sc-name sc))
  45.           (sb (sc-sb sc))
  46.           (sb-name (sb-name sb)))
  47.      (or (eq sc-name 'zero)
  48.          (eq sc-name 'null)
  49.          (eq sb-name 'registers)))))
  50.  
  51. (defun tn-register-number (tn)
  52.   (sc-case tn
  53.     (zero zero-offset)
  54.     (null null-offset)
  55.     (t (tn-offset tn))))
  56.  
  57. (define-argument-type register
  58.   :type '(satisfies register-p)
  59.   :function tn-register-number
  60.   :disassem-printer #'(lambda (value stream)
  61.             (format stream "$~A" (aref *register-names* value))))
  62.  
  63. (defun fp-reg-p (object)
  64.   (and (tn-p object)
  65.        (eq (sb-name (sc-sb (tn-sc object)))
  66.        'float-registers)))
  67.  
  68. (define-argument-type fp-reg
  69.   :type '(satisfies fp-reg-p)
  70.   :function tn-offset
  71.   :disassem-printer #'(lambda (value stream)
  72.             (format stream "$~A~D" 'f value)))
  73.  
  74. (define-argument-type odd-fp-reg
  75.   :type '(satisfies fp-reg-p)
  76.   :function (lambda (tn)
  77.           (1+ (tn-offset tn))))
  78.  
  79. (define-argument-type control-register
  80.   :type '(unsigned-byte 5)
  81.   :function identity)
  82.  
  83. (defun label-offset (label)
  84.   (1- (ash (- (label-position label) *current-position*) -2)))
  85.  
  86. (define-argument-type relative-label
  87.   :type 'label
  88.   :function label-offset
  89.   :sign-extend t
  90.   :disassem-use-label #'(lambda (value dstate)
  91.               (declare (type disassem:disassem-state dstate))
  92.               (+ (ash value 2) (disassem:dstate-curpos dstate))))
  93.  
  94. (defun float-format-value (format)
  95.   (ecase format
  96.     ((:s :single) 0)
  97.     ((:d :double) 1)
  98.     ((:w :word) 4)))
  99.  
  100. (define-argument-type float-format
  101.   :type '(member :s :single :d :double :w :word)
  102.   :function float-format-value)
  103.  
  104.  
  105. (defconstant compare-kinds
  106.   '(:f :un :eq :ueq :olt :ult :ole :ule :sf :ngle :seq :ngl :lt :nge :le :ngt))
  107. (defconstant compare-kinds-vec
  108.   (map 'vector #'symbol-name compare-kinds))
  109.  
  110. (defun compare-kind (kind)
  111.   (or (position kind compare-kinds)
  112.       (error "Unknown floating point compare kind: ~S~%Must be one of: ~S"
  113.          kind
  114.          compare-kinds)))
  115.  
  116. (define-argument-type compare-kind
  117.   :type `(member ,@compare-kinds)
  118.   :function compare-kind
  119.   :disassem-printer compare-kinds-vec)
  120.  
  121.  
  122. (defconstant float-operations '(+ - * /))
  123. (defconstant float-operations-vec
  124.   (map 'vector #'symbol-name float-operations))
  125.  
  126. (defun float-operation (op)
  127.   (or (position op float-operations)
  128.       (error "Unknown floating point operation: ~S~%Must be one of: ~S"
  129.          op
  130.          float-operations)))
  131.  
  132. (define-argument-type float-operation
  133.   :type `(member ,@float-operations)
  134.   :function float-operation
  135.   :disassem-printer float-operations-vec)
  136.  
  137. (define-fixup-type :jump)
  138. (define-fixup-type :lui)
  139. (define-fixup-type :addi)
  140.  
  141.  
  142.  
  143. ;;;; Formats.
  144.  
  145. (defconstant special-op #b000000)
  146. (defconstant bcond-op #b0000001)
  147. (defconstant cop0-op #b010000)
  148. (defconstant cop1-op #b010001)
  149. (defconstant cop2-op #b010010)
  150. (defconstant cop3-op #b010011)
  151.  
  152.  
  153. (define-format (immediate 32
  154.         :disassem-printer '(:name :tab
  155.                     rt ", "
  156.                     (:unless (:same-as rt) rs ", ")
  157.                     immediate))
  158.   (op (byte 6 26))
  159.   (rs (byte 5 21) :read t :default-type register)
  160.   (rt (byte 5 16) :write t :default-type register)
  161.   (immediate (byte 16 0) :default-type (signed-byte 16)))
  162.  
  163. (define-format (jump 32
  164.         :disassem-printer '(:name :tab target))
  165.   (op (byte 6 26))
  166.   (target (byte 26 0)))
  167.  
  168. (define-format (register 32
  169.         :disassem-printer '(:name :tab rd ", "
  170.                     (:unless (:same-as rd) rs ", ")
  171.                     rt))
  172.   (op (byte 6 26))
  173.   (rs (byte 5 21) :read t)
  174.   (rt (byte 5 16) :read t)
  175.   (rd (byte 5 11) :write t)
  176.   (shamt (byte 5 6) :default 0)
  177.   (funct (byte 6 0)))
  178.  
  179.  
  180. (define-format (break 32
  181.         :disassem-printer
  182.         '(:name :tab code (:unless (:constant 0) subcode)))
  183.   (op (byte 6 26) :default special-op)
  184.   (code (byte 10 16))
  185.   (subcode (byte 10 6) :default 0)
  186.   (funct (byte 6 0) :default #b001101))
  187.  
  188.  
  189. (define-format (coproc-branch 32 :use (float-status))
  190.   (op (byte 6 26))
  191.   (funct (byte 10 16))
  192.   (offset (byte 16 0)))
  193.  
  194. (define-format (float 32 :use (float-status) :clobber (float-status)
  195.         :disassem-printer '(name :tab fd ", " fs "," ft))
  196.   (op (byte 6 26) :default #b010001)
  197.   (filler (byte 1 25) :default #b1)
  198.   (format (byte 4 21))
  199.   (ft (byte 5 16) :read t)
  200.   (fs (byte 5 11) :read t)
  201.   (fd (byte 5 6) :write t)
  202.   (funct (byte 6 0)))
  203.  
  204. (define-format (float-aux 32 :use (float-status) :clobber (float-status))
  205.   (op (byte 6 26) :default #b010001)
  206.   (filler-1 (byte 1 25) :default #b1)
  207.   (format (byte 4 21))
  208.   (ft (byte 5 16) :read t :default 0)
  209.   (fs (byte 5 11) :read t)
  210.   (fd (byte 5 6) :write t)
  211.   (funct (byte 2 4))
  212.   (sub-funct (byte 4 0)))
  213.  
  214.  
  215.  
  216. ;;;; Instructions.
  217.  
  218.  
  219. (defmacro define-math-inst (name r3 imm &optional imm-type function fixup)
  220.   `(define-instruction (,name)
  221.      ,@(when imm
  222.      `((immediate (op :constant ,imm)
  223.               (rt :argument register)
  224.               (rs :same-as rt)
  225.               (immediate :argument (,(case imm-type
  226.                            (:signed 'signed-byte)
  227.                            (:unsigned 'unsigned-byte))
  228.                         16)
  229.                  ,@(when function
  230.                      `(:function ,function))))
  231.        (immediate (op :constant ,imm)
  232.               (rt :argument register)
  233.               (rs :argument register)
  234.               (immediate :argument (,(case imm-type
  235.                            (:signed 'signed-byte)
  236.                            (:unsigned 'unsigned-byte))
  237.                         16)
  238.                  ,@(when function
  239.                      `(:function ,function))))))
  240.      ,@(when (and imm fixup)
  241.      `((immediate (op :constant ,imm)
  242.               (rt :argument register)
  243.               (rs :same-as rt)
  244.               (immediate :argument addi-fixup))
  245.        (immediate (op :constant ,imm)
  246.               (rt :argument register)
  247.               (rs :argument register)
  248.               (immediate :argument addi-fixup))))
  249.      ,@(when r3
  250.      `((register (op :constant special-op)
  251.              (rd :argument register)
  252.              (rs :argument register)
  253.              (rt :argument register)
  254.              (funct :constant ,r3))
  255.        (register (op :constant special-op)
  256.              (rd :argument register)
  257.              (rs :same-as rd)
  258.              (rt :argument register)
  259.              (funct :constant ,r3))))))
  260.  
  261. (define-math-inst add #b100000 #b001000 :signed)
  262. (define-math-inst addu #b100001 #b001001 :signed nil t)
  263. (define-math-inst sub #b100010 #b001000 :signed -)
  264. (define-math-inst subu #b100011 #b001001 :signed -)
  265. (define-math-inst and #b100100 #b001100 :unsigned)
  266. (define-math-inst or #b100101 #b001101 :unsigned)
  267. (define-math-inst xor #b100110 #b001110 :unsigned)
  268. (define-math-inst nor #b100111 #b001111 :unsigned)
  269.  
  270. (define-math-inst slt #b101010 #b001010 :signed)
  271. (define-math-inst sltu #b101011 #b001011 :signed)
  272.  
  273. (define-instruction (beq :pinned t
  274.              :attributes (relative-branch delayed-branch))
  275.   (immediate (op :constant #b000100)
  276.          (rs :argument register)
  277.          (rt :constant 0)
  278.          (immediate :argument relative-label))
  279.   (immediate (op :constant #b000100)
  280.          (rs :argument register)
  281.          (rt :argument register :read t :write nil)
  282.          (immediate :argument relative-label)))
  283.  
  284. (define-instruction (bne :pinned t
  285.              :attributes (relative-branch delayed-branch))
  286.   (immediate (op :constant #b000101)
  287.          (rs :argument register)
  288.          (rt :constant 0)
  289.          (immediate :argument relative-label))
  290.   (immediate (op :constant #b000101)
  291.          (rs :argument register)
  292.          (rt :argument register :read t :write nil)
  293.          (immediate :argument relative-label)))
  294.  
  295. (define-instruction (blez :pinned t
  296.               :attributes (relative-branch delayed-branch))
  297.   (immediate (op :constant #b000110)
  298.          (rs :argument register)
  299.          (rt :constant 0)
  300.          (immediate :argument relative-label)))
  301.  
  302. (define-instruction (bgtz :pinned t
  303.               :attributes (relative-branch delayed-branch))
  304.   (immediate (op :constant #b000111)
  305.          (rs :argument register)
  306.          (rt :constant 0)
  307.          (immediate :argument relative-label)))
  308.  
  309. (define-instruction (bltz :pinned t
  310.               :attributes (relative-branch delayed-branch))
  311.   (immediate (op :constant bcond-op)
  312.          (rs :argument register)
  313.          (rt :constant #b00000)
  314.          (immediate :argument relative-label)))
  315.  
  316. (define-instruction (bgez :pinned t
  317.               :attributes (relative-branch delayed-branch))
  318.   (immediate (op :constant bcond-op)
  319.          (rs :argument register)
  320.          (rt :constant #b00001)
  321.          (immediate :argument relative-label)))
  322.  
  323. (define-instruction (bltzal :pinned t
  324.                 :attributes (relative-branch delayed-branch))
  325.   (immediate (op :constant bcond-op)
  326.          (rs :argument register)
  327.          (rt :constant #b01000)
  328.          (immediate :argument relative-label)))
  329.  
  330. (define-instruction (bgezal :pinned t
  331.                 :attributes (relative-branch delayed-branch))
  332.   (immediate (op :constant bcond-op)
  333.          (rs :argument register)
  334.          (rt :constant #b01001)
  335.          (immediate :argument relative-label)))
  336.  
  337. (define-instruction (bc1f :pinned t
  338.               :attributes (relative-branch delayed-branch))
  339.   (coproc-branch (op :constant cop1-op)
  340.          (funct :constant #x100)
  341.          (offset :argument relative-label)))
  342.  
  343. (define-instruction (bc1t :pinned t
  344.               :attributes (relative-branch delayed-branch))
  345.   (coproc-branch (op :constant cop1-op)
  346.          (funct :constant #x101)
  347.          (offset :argument relative-label)))
  348.  
  349. (define-instruction (break :pinned t)
  350.   (break (code :argument (unsigned-byte 10)))
  351.   (break (code :argument (unsigned-byte 10))
  352.      (subcode :argument (unsigned-byte 10))))
  353.  
  354. (define-instruction (div :clobber (low high))
  355.   (register (op :constant special-op)
  356.         (rs :argument register)
  357.         (rt :argument register)
  358.         (rd :constant 0)
  359.         (funct :constant #b011010)))
  360.  
  361. (define-instruction (divu :clobber (low high))
  362.   (register (op :constant special-op)
  363.         (rs :argument register)
  364.         (rt :argument register)
  365.         (rd :constant 0)
  366.         (funct :constant #b011011)))
  367.  
  368. (define-instruction (j :pinned t
  369.                :attributes (unconditional-branch delayed-branch))
  370.   (register (op :constant special-op)
  371.         (rs :argument register)
  372.         (rt :constant 0)
  373.         (rd :constant 0)
  374.         (funct :constant #b001000))
  375.   (jump (op :constant #b000010)
  376.     (target :argument jump-fixup)))
  377.  
  378. (define-instruction (jal :pinned t
  379.              :attributes (delayed-branch assembly-call))
  380.   (register (op :constant special-op)
  381.         (rs :argument register)
  382.         (rt :constant 0)
  383.         (rd :constant 31)
  384.         (funct :constant #b001001))
  385.   (register (op :constant special-op)
  386.         (rd :argument register)
  387.         (rs :argument register)
  388.         (rt :constant 0)
  389.         (funct :constant #b001001))
  390.   (jump (op :constant #b000011)
  391.     (target :argument jump-fixup)))
  392.  
  393.  
  394. (defmacro define-load/store-instruction (name read-p op
  395.                           &optional (rt-kind 'register))
  396.   `(define-instruction (,name ,@(if read-p
  397.                     '(:use (memory) :attributes (delayed-load))
  398.                     '(:clobber (memory))))
  399.      (immediate (op :constant ,op)
  400.         (rt :argument ,rt-kind ,@(unless read-p
  401.                        '(:read t :write nil)))
  402.         (rs :argument register)
  403.         (immediate :argument (signed-byte 16)))
  404.      (immediate (op :constant ,op)
  405.         (rt :argument ,rt-kind ,@(unless read-p
  406.                        '(:read t :write nil)))
  407.         (rs :argument register)
  408.         (immediate :argument addi-fixup))
  409.      (immediate (op :constant ,op)
  410.         (rt :argument ,rt-kind ,@(unless read-p
  411.                        '(:read t :write nil)))
  412.         (rs :argument register)
  413.         (immediate :constant 0))))
  414.  
  415. (define-load/store-instruction lb t #b100000)
  416. (define-load/store-instruction lh t #b100001)
  417. (define-load/store-instruction lwl t #b100010)
  418. (define-load/store-instruction lw t #b100011)
  419. (define-load/store-instruction lbu t #b100100)
  420. (define-load/store-instruction lhu t #b100101)
  421. (define-load/store-instruction lwr t #b100110)
  422. (define-load/store-instruction lwc1 t #o61 fp-reg)
  423. (define-load/store-instruction lwc1-odd t #o61 odd-fp-reg)
  424. (define-load/store-instruction sb nil #b101000)
  425. (define-load/store-instruction sh nil #b101001)
  426. (define-load/store-instruction swl nil #b101010)
  427. (define-load/store-instruction sw nil #b101011)
  428. (define-load/store-instruction swr nil #b101110)
  429. (define-load/store-instruction swc1 nil #o71 fp-reg)
  430. (define-load/store-instruction swc1-odd nil #o71 odd-fp-reg)
  431.  
  432. (define-instruction (lui)
  433.   (immediate (op :constant #b001111)
  434.          (rs :constant 0)
  435.          (rt :argument register)
  436.          (immediate :argument (or (unsigned-byte 16) (signed-byte 16))))
  437.   (immediate (op :constant #b001111)
  438.          (rs :constant 0)
  439.          (rt :argument register)
  440.          (immediate :argument lui-fixup)))
  441.  
  442.  
  443. (define-instruction (mfhi :use (high))
  444.   (register (op :constant special-op)
  445.         (rd :argument register)
  446.         (rs :constant 0)
  447.         (rt :constant 0)
  448.         (funct :constant #b010000)))
  449.  
  450. (define-instruction (mthi :clobber (high))
  451.   (register (op :constant special-op)
  452.         (rd :argument register)
  453.         (rs :constant 0)
  454.         (rt :constant 0)
  455.         (funct :constant #b010001)))
  456.  
  457. (define-instruction (mflo :use (low))
  458.   (register (op :constant special-op)
  459.         (rd :argument register)
  460.         (rs :constant 0)
  461.         (rt :constant 0)
  462.         (funct :constant #b010010)))
  463.  
  464. (define-instruction (mtlo :clobber (low))
  465.   (register (op :constant special-op)
  466.         (rd :argument register)
  467.         (rs :constant 0)
  468.         (rt :constant 0)
  469.         (funct :constant #b010011)))
  470.  
  471.  
  472. (define-instruction (mult :clobber (low high))
  473.   (register (op :constant special-op)
  474.         (rs :argument register)
  475.         (rt :argument register)
  476.         (rd :constant 0)
  477.         (funct :constant #b011000)))
  478.  
  479. (define-instruction (multu :clobber (low high))
  480.   (register (op :constant special-op)
  481.         (rs :argument register)
  482.         (rt :argument register)
  483.         (rd :constant 0)
  484.         (funct :constant #b011001)))
  485.  
  486. (define-instruction (sll)
  487.   (register (op :constant special-op)
  488.         (rd :argument register)
  489.         (rt :argument register)
  490.         (rs :constant 0)
  491.         (shamt :argument (unsigned-byte 5))
  492.         (funct :constant #b000000))
  493.   (register (op :constant special-op)
  494.         (rd :argument register)
  495.         (rt :same-as rd)
  496.         (rs :constant 0)
  497.         (shamt :argument (unsigned-byte 5))
  498.         (funct :constant #b000000))
  499.   (register (op :constant special-op)
  500.         (rd :argument register)
  501.         (rt :argument register)
  502.         (rs :argument register)
  503.         (funct :constant #b000100))
  504.   (register (op :constant special-op)
  505.         (rd :argument register)
  506.         (rt :same-as rd)
  507.         (rs :argument register)
  508.         (funct :constant #b000100)))
  509.  
  510. (define-instruction (sra)
  511.   (register (op :constant special-op)
  512.         (rd :argument register)
  513.         (rt :argument register)
  514.         (rs :constant 0)
  515.         (shamt :argument (unsigned-byte 5))
  516.         (funct :constant #b000011))
  517.   (register (op :constant special-op)
  518.         (rd :argument register)
  519.         (rt :same-as rd)
  520.         (rs :constant 0)
  521.         (shamt :argument (unsigned-byte 5))
  522.         (funct :constant #b000011))
  523.   (register (op :constant special-op)
  524.         (rd :argument register)
  525.         (rt :argument register)
  526.         (rs :argument register)
  527.         (funct :constant #b000111))
  528.   (register (op :constant special-op)
  529.         (rd :argument register)
  530.         (rt :same-as rd)
  531.         (rs :argument register)
  532.         (funct :constant #b000111)))
  533.  
  534. (define-instruction (srl)
  535.   (register (op :constant special-op)
  536.         (rd :argument register)
  537.         (rt :argument register)
  538.         (rs :constant 0)
  539.         (shamt :argument (unsigned-byte 5))
  540.         (funct :constant #b000010))
  541.   (register (op :constant special-op)
  542.         (rd :argument register)
  543.         (rt :same-as rd)
  544.         (rs :constant 0)
  545.         (shamt :argument (unsigned-byte 5))
  546.         (funct :constant #b000010))
  547.   (register (op :constant special-op)
  548.         (rd :argument register)
  549.         (rt :argument register)
  550.         (rs :argument register)
  551.         (funct :constant #b000110))
  552.   (register (op :constant special-op)
  553.         (rd :argument register)
  554.         (rt :same-as rd)
  555.         (rs :argument register)
  556.         (funct :constant #b000110)))
  557.  
  558. (define-instruction (syscall :pinned t)
  559.   (register (op :constant special-op)
  560.         (rd :constant 0)
  561.         (rt :constant 0)
  562.         (rs :constant 0)
  563.         (funct :constant #b001100)))
  564.  
  565.  
  566.  
  567. ;;;; Floating point instructions.
  568.  
  569. (macrolet ((frob (name kind)
  570.          `(define-instruction (,name :attributes (delayed-load))
  571.         (register (op :constant #b010001)
  572.               (rs :constant #b00100)
  573.               (rd :argument ,kind)
  574.               (rt :argument register)
  575.               (funct :constant 0)))))
  576.   (frob mtc1 fp-reg)
  577.   (frob mtc1-odd odd-fp-reg))
  578.  
  579. (macrolet ((frob (name kind)
  580.          `(define-instruction (,name :attributes (delayed-load))
  581.         (register (op :constant #b010001)
  582.               (rs :constant #b00000)
  583.               (rt :argument register :read nil :write t)
  584.               (rd :argument ,kind :write nil :read t)
  585.               (funct :constant 0)))))
  586.   (frob mfc1 fp-reg)
  587.   (frob mfc1-odd odd-fp-reg))
  588.  
  589. (define-instruction (cfc1 :use (float-status) :attributes (delayed-load))
  590.   (register (op :constant #b010001)
  591.         (rs :constant #b00010)
  592.         (rt :argument register :read nil :write t)
  593.         (rd :argument control-register :write nil)
  594.         (funct :constant 0)))
  595.  
  596. (define-instruction (ctc1 :use (float-status) :clobber (float-status)
  597.               :attributes (delayed-load))
  598.   (register (op :constant #b010001)
  599.         (rs :constant #b00110)
  600.         (rt :argument register)
  601.         (rd :argument control-register :write nil)
  602.         (funct :constant 0)))
  603.  
  604. (define-instruction (float-op)
  605.   (float (funct :argument float-operation)
  606.      (format :argument float-format)
  607.      (fd :argument fp-reg)
  608.      (fs :argument fp-reg)
  609.      (ft :argument fp-reg)))
  610.  
  611.  
  612. (define-instruction (fabs)
  613.   (float (format :argument float-format)
  614.      (ft :constant 0)
  615.      (fd :argument fp-reg)
  616.      (fs :argument fp-reg)
  617.      (funct :constant #b000101))
  618.   (float (format :argument float-format)
  619.      (ft :constant 0)
  620.      (fd :argument fp-reg)
  621.      (fs :same-as fd)
  622.      (funct :constant #b000101)))
  623.  
  624. (define-instruction (fneg)
  625.   (float (format :argument float-format)
  626.      (ft :constant 0)
  627.      (fd :argument fp-reg)
  628.      (fs :argument fp-reg)
  629.      (funct :constant #b000111))
  630.   (float (format :argument float-format)
  631.      (ft :constant 0)
  632.      (fd :argument fp-reg)
  633.      (fs :same-as fd)
  634.      (funct :constant #b000111)))
  635.  
  636.  
  637. (define-instruction (fcvt)
  638.   (float-aux (sub-funct :argument float-format)
  639.          (format :argument float-format)
  640.          (fd :argument fp-reg)
  641.          (fs :argument fp-reg)
  642.          (funct :constant #b10)))
  643.  
  644.   
  645. (define-instruction (fcmp)
  646.   (float-aux (sub-funct :argument compare-kind)
  647.          (format :argument float-format)
  648.          (fd :constant 0)
  649.          (fs :argument fp-reg)
  650.          (ft :argument fp-reg)
  651.          (funct :constant #b11)))
  652.  
  653.  
  654. ;;;; Pseudo-instructions
  655.  
  656. (define-instruction (move
  657.              :disassem-printer '(:name :tab rd ", " rs))
  658.   (register (op :constant special-op)
  659.         (rd :argument register)
  660.         (rs :argument register)
  661.         (rt :constant 0)
  662.         (funct :constant #b100001))
  663.   (float (format :argument float-format)
  664.      (fd :argument fp-reg)
  665.      (fs :argument fp-reg)
  666.      (ft :constant 0)
  667.      (funct :constant #b000110)))
  668.  
  669. (define-pseudo-instruction li 64 (reg value)
  670.   (etypecase value
  671.     ((unsigned-byte 16)
  672.      (inst or reg zero-tn value))
  673.     ((signed-byte 16)
  674.      (inst addu reg zero-tn value))
  675.     ((or (signed-byte 32) (unsigned-byte 32))
  676.      (inst lui reg (ldb (byte 16 16) value))
  677.      (let ((low (ldb (byte 16 0) value)))
  678.        (unless (zerop low)
  679.      (inst or reg low))))
  680.     (fixup
  681.      (inst lui reg value)
  682.      (inst addu reg value))))
  683.  
  684. (define-instruction (b :pinned t
  685.                :attributes (relative-branch unconditional-branch
  686.                             delayed-branch))
  687.   (immediate (op :constant #b000100)
  688.          (rs :constant 0)
  689.          (rt :constant 0)
  690.          (immediate :argument relative-label)))
  691.  
  692. (define-instruction (nop :attributes (nop)
  693.              :disassem-printer '(:name))
  694.   (register (op :constant 0)
  695.         (rd :constant 0)
  696.         (rt :constant 0)
  697.         (rs :constant 0)
  698.         (funct :constant 0)))
  699.  
  700. (define-format (word-format 32 :pinned t)
  701.   (data (byte 32 0)))
  702. (define-instruction (word :cost 0)
  703.   (word-format (data :argument (or (unsigned-byte 32) (signed-byte 32)))))
  704.  
  705. (define-format (short-format 16 :pinned t)
  706.   (data (byte 16 0)))
  707. (define-instruction (short :cost 0)
  708.   (short-format (data :argument (or (unsigned-byte 16) (signed-byte 16)))))
  709.  
  710. (define-format (byte-format 8 :pinned t)
  711.   (data (byte 8 0)))
  712. (define-instruction (byte :cost 0)
  713.   (byte-format (data :argument (or (unsigned-byte 8) (signed-byte 8)))))
  714.  
  715.  
  716.  
  717. ;;;; Function and LRA Headers emitters and calculation stuff.
  718.  
  719. (define-format (entry-point 0 :pinned t))
  720. (define-instruction (entry-point)
  721.   (entry-point))
  722.  
  723. (defun header-data (ignore)
  724.   (declare (ignore ignore))
  725.   (ash (+ *current-position* (component-header-length)) (- vm:word-shift)))
  726.  
  727. (define-format (header-object 32 :pinned t)
  728.   (type (byte 8 0))
  729.   (data (byte 24 8) :default 0 :function header-data))
  730.  
  731. (define-instruction (function-header-word)
  732.   (header-object (type :constant vm:function-header-type)))
  733.  
  734. (define-instruction (lra-header-word)
  735.   (header-object (type :constant vm:return-pc-header-type)))
  736.  
  737.  
  738. (defmacro define-compute-instruction (name calculation)
  739.   (let ((addui (symbolicate name "-ADDUI"))
  740.     (lui (symbolicate name "-LUI"))
  741.     (ori (symbolicate name "-ORI")))
  742.     `(progn
  743.        (defun ,name (label)
  744.      (let ((result ,calculation))
  745.        (assert (typep result '(signed-byte 16)))
  746.        result))
  747.        (define-instruction (,addui)
  748.      (immediate (op :constant #b001001)
  749.             (rt :argument register)
  750.             (rs :argument register)
  751.             (immediate :argument label
  752.                    :function ,name)))
  753.        (define-instruction (,lui)
  754.      (immediate (op :constant #b001111)
  755.             (rs :constant 0)
  756.             (rt :argument register :read t)
  757.             (immediate :argument label
  758.                    :function (lambda (label)
  759.                        (ash ,calculation -16)))))
  760.        (define-instruction (,ori)
  761.      (immediate (op :constant #b001101)
  762.             (rt :argument register)
  763.             (rs :same-as rt)
  764.             (immediate :argument label
  765.                    :function (lambda (label)
  766.                        (logand ,calculation #xffff)))))
  767.        (define-pseudo-instruction ,name 96 (dst src label temp)
  768.      (cond ((typep ,calculation '(signed-byte 16))
  769.         (inst ,addui dst src label))
  770.            (t
  771.         (inst ,lui temp label)
  772.         (inst ,ori temp label)
  773.         (inst addu dst src temp)))))))
  774.  
  775.  
  776. ;; code = fn - header - label-offset + other-pointer-tag
  777. (define-compute-instruction compute-code-from-fn
  778.                 (- vm:other-pointer-type
  779.                    (label-position label)
  780.                    (component-header-length)))
  781.  
  782. ;; code = lra - other-pointer-tag - header - label-offset + other-pointer-tag
  783. (define-compute-instruction compute-code-from-lra
  784.                 (- (+ (label-position label)
  785.                   (component-header-length))))
  786.  
  787. ;; lra = code + other-pointer-tag + header + label-offset - other-pointer-tag
  788. (define-compute-instruction compute-lra-from-code
  789.                 (+ (label-position label)
  790.                    (component-header-length)))
  791.